package com.xiaoma.verbal.service;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.xiaoma.tpo.utils.Pager;
import com.xiaoma.verbal.dao.PrctPracticeAudioDao;
import com.xiaoma.verbal.dao.QuClassicDao;
import com.xiaoma.verbal.dao.QuQuestionDao;
import com.xiaoma.verbal.dao.QuTagDao;
import com.xiaoma.verbal.dao.TagTableDao;
import com.xiaoma.verbal.domain.QuClassic;
import com.xiaoma.verbal.domain.QuQuestion;
import com.xiaoma.verbal.domain.QuTag;
import com.xiaoma.verbal.domain.TagTable;
import com.xiaoma.verbal.dto.QuClassicVo;
import com.xiaoma.verbal.dto.QuestionVo;
import com.xiaoma.verbal.utils.Constants;
import com.xiaoma.verbal.utils.ExcelUtil;
import com.xiaoma.verbal.utils.MemoryDB;
import com.xiaoma.verbal.utils.UUIDGenerator;

@Service
public class QuClassicService extends BaseQuestionService {
	@Autowired
	private QuQuestionDao quQuestionDao;
	@Autowired
	private QuClassicDao quClassicDao;
	@Autowired
	private QuTagDao quTagDao;
	@Autowired
	private TagTableDao tagTableDao;
	@Autowired
	private PrctPracticeAudioDao prctPracticeAudioDao;

	@SuppressWarnings("unchecked")
	public QuClassicVo findClassicByCheckUpdate(Boolean checkUpdate, Long lastUpdateTime) throws IllegalAccessException, InvocationTargetException {
		QuClassicVo vo = new QuClassicVo();
		if (checkUpdate != null && checkUpdate) {
			if (this.hasUpdate(lastUpdateTime, vo, true)) {
				vo.setQuestions(this.findClassic());
				vo.setUpdateTime(this.getTimeCoordinate());
				vo.setHasUpdate(true);
				return vo;
			}
		}
		vo.setQuestions(new ArrayList<QuestionVo>());
		vo.setHasUpdate(false);
		vo.setUpdateTime(lastUpdateTime);
		return vo;

	}

	public Pager list(Integer id, String qnum, String tagText, String content, Integer page, Integer pageSize) {
		if (page == null || page == 0) {
			page = 1;
			pageSize = 50;
		}
		Pager pager = quClassicDao.queryPageList(id, qnum, tagText, content, (page - 1) * pageSize, pageSize);
		List<QuestionVo> list = pager.getList();
		for (QuestionVo vo : list) {
			vo.setTags(this.quTagDao.findTagByQuestionId(vo.getId()));
		}

		return pager;
	}

	public Boolean hasUpdate(Long lastUpdateTime, QuClassicVo vo, Boolean cacheAble) {
		if (lastUpdateTime == null)
			return true;
		Long timeCoordinate = 0L;

		if (cacheAble) {
			timeCoordinate = (Long) MemoryDB.get(Constants.QCTC);
		} else {
			timeCoordinate = this.quClassicDao.getTimeCoordinate();
		}
		vo.setUpdateTime(timeCoordinate);

		if (lastUpdateTime.longValue() != timeCoordinate.longValue())
			return true;
		return false;
	}

	@SuppressWarnings("unchecked")
	public List<QuestionVo> findClassic() throws IllegalAccessException, InvocationTargetException {
		List<QuestionVo> volist = this.quClassicDao.findClassic();
		for (QuestionVo bean : volist) {
			bean.setTags(this.quTagDao.findTagByQuestionId(bean.getId()));
		}
		return volist;

	}

	@SuppressWarnings("unchecked")
	public Long getTimeCoordinate() {
		return this.quClassicDao.getTimeCoordinate();
	}

	@Transactional(rollbackFor = Exception.class)
	public int importData(int version, InputStream fis) // TODO Auto-generated
			// method stub
			throws Exception {
		// TODO Auto-generated method stub
		List<Map<String, Object>> list = null;
		try {
			// excel数据
			if (version == 2003) {
				list = ExcelUtil.parseExcel_2003(fis);
			} else {
				list = ExcelUtil.parseExcel_2007(fis);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return 2;
		}
		try {
//			this.quClassicDao.deleteAll();
			// 保存数据
			for (Map<String, Object> m : list) {
				saveDate(m, 0);

			}
		} catch (Exception e) {
			throw e;
		}
		// 刷新缓存
		this.afterChanger();
		return 1;
	}

	private void saveDate(Map<String, Object> map, int type) throws Exception {
		final String qNum = (String) map.get("question_num");
		final String idstr = (String) map.get("qid");// 导入时此项不存在
		final Integer bankType = (Integer) map.get("bankType");

		if (qNum != null && qNum.length() > 0) {

			// 保存或更新题
			// 导入时通过题号判断是否已存在，存在的话则覆盖
			QuQuestion oldqb = quQuestionDao.findByQnum(qNum);
			System.out.println(qNum);
			if (oldqb != null) {
				if (type == 0) {
					dealKyQb(oldqb, map, type);
				}
			} else {
				QuQuestion qb = new QuQuestion();
				// id不为空则更新
				if (idstr != null && idstr.length() > 0) {
					qb.setId(Integer.parseInt(idstr));
				}
				if (type == 0) {
					dealKyQb(qb, map, type);
				}
			}
		}

	}

	/**
	 * 处理题库--口语
	 * 
	 * @param qb
	 * @throws Exception
	 */
	@SuppressWarnings("deprecation")
	private void dealKyQb(QuQuestion qb, Map<String, Object> rowmap, int type) throws Exception {

		final String idstr = (String) rowmap.get("qid");// 导入时此项不存在,单个修改时才不为空
		final String qNum = (String) rowmap.get("question_num");
		final String content = (String) rowmap.get("content");
		final String tags = (String) rowmap.get("tags");
		final String translation = (String) rowmap.get("translation");
		final String keyword_audiourls = (String) rowmap.get("keyword_audiourl");
		final String review = (String) rowmap.get("review");// 老师点评

		/** tpo题库 start ***/
		// final String taskNum = (String) rowmap.get("task_num");
		// final String tpoNum = (String) rowmap.get("tpo_num");
		// final String timeLimit = (String) rowmap.get("time_limit");
		// if (taskNum != null) {
		// qb.setTaskNum(Double.valueOf(taskNum).intValue());
		// }
		// if (tpoNum != null) {
		// qb.setTpoNum(Double.valueOf(tpoNum).intValue());
		// }
		// if (timeLimit != null) {
		// qb.setTimeLimit(Double.valueOf(timeLimit).intValue());
		// }
		/** tpo题库 end ***/
		if (qNum.startsWith("W_")) {
			// 错误，口语是以S_开头
			throw new Exception("内容有误，应该上传口语");
		}

		qb.setQuestionNum(qNum);
		if ((content != null && content.length() > 0) || idstr != null) {
			qb.setContent(content);
		}
		if ((translation != null && translation.length() > 0) || idstr != null) {
			qb.setTranslation(translation);
		}
		qb.setQuestionType(type);

		if (qb.getId() != null && qb.getId() > 0) {
			qb.setUpdateTime(new Date());
		} else {
			Date date = new Date();
			qb.setCreateTime(date);
			qb.setUpdateTime(date);
		}
		if (qb.getId() != null) {
			quQuestionDao.update(qb);
		} else {
			qb.setId(quQuestionDao.insert(qb));
		}

		// 题库标签
		dealTags(qb, tags, idstr, type);
		this.update(qb.getQuestionNum());
	}

	/**
	 * 处理标签
	 * 
	 * @param tags
	 * @param arryTags
	 * @throws Exception
	 */
	private void dealTags(QuQuestion qb, String tags, String idstr, int type) throws Exception {
		QuTag bean = new QuTag();
		bean.setQuestionId(qb.getId());
		List<QuTag> list = quTagDao.findByColumns(bean);
		for (QuTag q : list) {
			quTagDao.destroy(q.getId());
		}
		if (tags != null && tags.length() > 0) {
			for (String str : tags.split("/")) {
				if (StringUtils.hasText(str) && StringUtils.hasLength(str) && !"无".equals(str)) {

					if (str.length() > 3) {
						System.out.println(str.length());
						str = str.trim();
						System.out.println(str.length());
					}
					str = str.replace(" ", "");
					str = str.trim();
					TagTable tag = tagTableDao.findByTypeAndText(0, str);
					// 判断tag是否添加过
					if (tag == null) {
						tag = new TagTable();
						tag.setTagType(type);
						tag.setTagText(str);
						tag.setId(tagTableDao.insert(tag));
					}
					QuTag qtag = new QuTag();
					qtag.setQuestionId(qb.getId());
					qtag.setTagId(tag.getId());
					quTagDao.insert(qtag);
				}
			}
		}
	}

	@Transactional
	public void updateAll(String[] qnums) {
		// TODO Auto-generated method stub
		// this.quClassicDao.deleteAll();

		if (qnums != null) {
			for (String qnum : qnums) {
				this.update(qnum);
			}
		}
		// 刷新缓存
		this.afterChanger();
	}
	
	private void update(String qnum) {
		QuQuestion qst = this.quQuestionDao.findByQnum(qnum);
		if (qst != null) {
			QuClassic clsc = new QuClassic();
			clsc.setQuestionId(qst.getId());
			List<QuClassic> list = this.quClassicDao.findByColumns(clsc);
			String uuid = null;
			if (!CollectionUtils.isEmpty(list)) {
				for (QuClassic del : list) {
					uuid = del.getUuid();
					this.quClassicDao.destroy(del.getId());
				}
			}
			clsc.setCreateTime(new Date());
			clsc.setUpdateTime(clsc.getCreateTime());
			clsc.setUuid(uuid != null ? uuid : UUIDGenerator.getUUID());
			this.quClassicDao.insert(clsc);
		}
	
	}
	/**
	 * 
	 *新的 
	 * 
	 */
	//新的
	@SuppressWarnings("unchecked")
	public QuClassicVo findClassicByCheckUpdate(Boolean checkUpdate, Long lastUpdateTime,Integer clsClassId,Integer userId) throws IllegalAccessException, InvocationTargetException {
		
		QuClassicVo vo = new QuClassicVo();
		if (checkUpdate != null && checkUpdate) {
			if (this.hasUpdate(lastUpdateTime, vo, true)) {
				vo.setQuestions(this.findClassic(clsClassId, userId));
				vo.setUpdateTime(this.getTimeCoordinate());
				vo.setHasUpdate(true);
				return vo;
			}
		}
		vo.setQuestions(new ArrayList<QuestionVo>());
		vo.setHasUpdate(false);
		vo.setUpdateTime(lastUpdateTime);
		return vo;

	}
	//新的
	@SuppressWarnings("unchecked")
	public List<QuestionVo> findClassic(Integer clsClassId,Integer userId) throws IllegalAccessException, InvocationTargetException {
		List<QuestionVo> volist = this.quClassicDao.findClassic();
		for (QuestionVo bean : volist) {
			bean.setTags(this.quTagDao.findTagByQuestionId(bean.getId()));
			boolean yonCommit = prctPracticeAudioDao.findbyClsIdAndQuestionNumAndUserId(clsClassId, bean.getQuestionNum(), userId);
			bean.setYonCommit(yonCommit);
		}
		return volist;

	}
}
